﻿using System;
using System.Runtime.Serialization;
using System.Windows.Ink;

namespace ThePresenter.Net.PresenterCom.Uids
{
	[Serializable]
	public class Uid : ISerializable
	{
		private Guid _Guid;

		public Uid()
		{
			_Guid = Guid.NewGuid();
		}

		#region ToByteArrayConverter
		// used when adding uid as stroke property which can only be Byte[]

		/// <summary>
		/// Initializes a new instance of the <see cref="Uid"/> class.
		/// </summary>
		/// <param name="b">The b.</param>
		public Uid(byte[] b)
		{
			this._Guid = new Guid(b);
		}

		/// <summary>
		/// Converts to the byte array.
		/// </summary>
		/// <returns>Byte[] representation of UID</returns>
		public byte[] ToByteArray()
		{
			return _Guid.ToByteArray();
		}
		#endregion

		/// <summary>
		/// Returns a <see cref="System.String"/> that represents this instance.
		/// </summary>
		/// <returns>
		/// A <see cref="System.String"/> that represents this instance.
		/// </returns>
		public override string ToString()
		{
			return _Guid.ToString();
		}

		#region ISerializable Members

		public Uid(SerializationInfo info, StreamingContext context)
		{
			_Guid = new Guid((byte[])info.GetValue("Guid", typeof(byte[])));
		}

		public void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			info.AddValue("Guid", _Guid.ToByteArray(), typeof(byte[]));
		}

		#endregion

		#region IEquatable<object> Members
		/// <summary>
		/// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
		/// </summary>
		/// <param name="other">The <see cref="System.Object"/> to compare with this instance.</param>
		/// <returns>
		/// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
		/// </returns>
		public override bool Equals(object other)
		{
			if (other is Uid)
			{
				return _Guid.Equals(((Uid)other)._Guid);
			}
			else
				return false;
		}

		/// <summary>
		/// Returns a hash code for this instance.
		/// </summary>
		/// <returns>
		/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
		/// </returns>
		public override int GetHashCode()
		{
			return _Guid.GetHashCode();
		}
		#endregion
	}

	public static class StrokeExtension
	{
		/// 2010746-5616d-3034-706b-737332303130 is guid from settings
		/// this has no particular value it is just
		/// "2010" + HEX("team04pkss10"_ascii)

		/// <summary>
		/// Gets the uid of stroke.
		/// </summary>
		/// <param name="s">The stroke.</param>
		/// <remarks>Defined in Uid.cs</remarks>
		/// <returns>Uid of given stroke</returns>
		public static Uid GetUid(this Stroke s)
		{
			return new Uid((byte[])s.GetPropertyData(ThePresenter.Properties.Settings.Default.ApplicationStrokeUIDGuid));
		}

		/// <summary>
		/// Sets the uid of given stroke.
		/// </summary>
		/// <param name="s">The stroke.</param>
		/// <param name="u">The uid.</param>
		/// <remarks>Defined in Uid.cs</remarks>
		public static void SetUid(this Stroke s, Uid u)
		{
			if (s.ContainsPropertyData(ThePresenter.Properties.Settings.Default.ApplicationStrokeUIDGuid))
				s.RemovePropertyData(ThePresenter.Properties.Settings.Default.ApplicationStrokeUIDGuid);

			s.AddPropertyData(ThePresenter.Properties.Settings.Default.ApplicationStrokeUIDGuid, u.ToByteArray());
		}
	}
}
